// 结合视频，再研读
#include <bits/stdc++.h>

#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
// 出变量名（通过#x字符串化）

#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define ROF(i, a, b) for (int i = (a); i >= (b); i--)
#define pb push_back
#define fi first
#define se second

using namespace std;
using ll = long long;

const int MAXN = 2e5 + 5;

/**
 * 算法核心思想：
 * 将所有的(l,r)对分成三类：
 * 1. A[l] > A[r]: f(l,r) < A (按字典序比较)
 * 2. A[l] = A[r]: f(l,r) = A
 * 3. A[l] < A[r]: f(l,r) > A
 *
 * 对于每一类，我们按照特定的三元组进行排序：
 * - 第一类：按(l, A[r], -r)排序
 * - 第二类：所有对都相等
 * - 第三类：按(-l, A[r], r)排序
 *
 * 多组询问离线处理：按k从小到大排序，依次处理三类情况
 */

template <typename T> class OrderedSet {
private:
  std::multiset<T> data;

public:
  void insert(const T &value) { data.insert(value); }

  void erase(const T &value) {
    auto it = data.find(value);
    if (it != data.end()) {
      data.erase(it);
    }
  }

  // 返回小于key的元素数量
  int order_of_key(const T &key) {
    return std::distance(data.begin(), data.lower_bound(key));
  }

  // 返回第pos小的元素
  const T &find_by_order(int pos) {
    if (pos >= data.size()) {
      throw std::out_of_range("Index out of range");
    }
    return *std::next(data.begin(), pos);
  }

  int size() const { return data.size(); }
  bool empty() const { return data.empty(); }
};

template <class T> using ordered_set = OrderedSet<T>;

int n, q;
int a[MAXN];
vector<pair<ll, int>> qry; // 存储询问(k, 询问id)
pair<int, int> ans[MAXN];  // 存储每个询问的答案(l, r)
int cnt[MAXN], las[MAXN];  // cnt统计每个值出现次数，las记录每个值最后出现位置

int main() {
  scanf("%d%d", &n, &q);
  FOR(i, 1, n) scanf("%d", a + i);

  // 读入所有询问并离线处理
  FOR(i, 1, q) {
    ll k;
    scanf("%lld", &k);
    qry.pb({k, i});
  }

  // 将询问按k从小到大排序，然后反转以便从后往前处理（使用pop_back）
  sort(qry.begin(), qry.end());
  reverse(qry.begin(), qry.end());

  ll now = 0; // 当前已经处理的对数

  // ==================== 第一部分：处理 A[l] > A[r] 的情况 ====================
  // 这类对按(l, A[r], -r)排序，f(l,r) < A
  ordered_set<pair<int, int>> S; // 存储(A[r], -r)，用于维护r>l的候选位置

  // 初始化：将所有位置插入集合，存储为(A[i], -i)
  FOR(i, 1, n) S.insert({a[i], -i});

  // 从左到右扫描l，每个l处理完后才处理下一个l，保证了l的递增顺序
  FOR(l, 1, n) {
    // 删除当前l对应的元素（因为r>l，所以l不能作为r）
    S.erase({a[l], -l});

    // 计算满足r>l且A[r] < A[l]的对数
    // 在有序集合中，小于(A[l], -∞)的元素数量就是满足A[r] < A[l]的对数
    ll lim = S.order_of_key({a[l], -1e9});

    // 处理当前l对应的询问
    while (!qry.empty()) {
      auto [k, id] = qry.back();
      ll k1 = k - now; // 在当前类别中的相对位置

      // 如果当前询问落在当前l的范围内
      if (k1 <= lim) {
        // 找到第k1小的对：在S中找第(k1-1)小的元素（因为从0开始计数）
        auto elem = S.find_by_order(k1 - 1);
        ans[id] = {l, -elem.second}; // 恢复r的原始索引
        qry.pop_back();
      } else
        break; // 当前询问不在这个l的范围内，继续下一个l
    }
    now += lim; // 累计已处理的对数
  }

  // ==================== 第二部分：处理 A[l] = A[r] 的情况 ====================
  // 这类对f(l,r) = A，所有对都相等，只需要任意选一个即可
  FOR(i, 1, n) las[i] = -1;
  int x = -1, y = -1; // 记录任意一对相同元素的位置

  // 统计每个值的出现次数，并找到第一对相同元素的位置
  FOR(i, 1, n) {
    ++cnt[a[i]];
    if (las[a[i]] == -1)
      las[a[i]] = i;
    else {
      if (x == -1 && y == -1) // 只记录第一对
        x = las[a[i]], y = i;
    }
  }

  // 计算相同元素对的总数：C(cnt, 2) = cnt*(cnt-1)/2
  FOR(i, 1, n) if (cnt[i]) now += 1ll * cnt[i] * (cnt[i] - 1) / 2;

  // 处理落在第二类的询问
  while (!qry.empty()) {
    auto [k, id] = qry.back();
    ll k1 = k - now;
    if (k1 <= 0) {      // 如果k在当前累计范围内
      ans[id] = {x, y}; // 返回任意一对相同元素
      qry.pop_back();
    } else
      break; // 剩下的询问属于第三类
  }

  // ==================== 第三部分：处理 A[l] < A[r] 的情况 ====================
  // 这类对按(-l, A[r], r)排序，f(l,r) > A
  // 从右到左扫描l
  ROF(l, n, 1) {
    // 计算满足A[r] > A[l]的对数
    // 先计算A[r] <= A[l]的数量，然后用总数减去
    int o = S.order_of_key({a[l], 1e9}); // A[r] <= A[l]的数量

    // 处理当前l对应的询问
    while (!qry.empty()) {
      auto [k, id] = qry.back();
      ll k1 = k - now;

      // 如果当前询问落在当前l的A[r] > A[l]范围内
      if (k1 <= (int)S.size() - o) {
        // 在A[r] > A[l]的部分中找第k1小的元素
        auto elem = S.find_by_order(o + k1 - 1);
        ans[id] = {l, elem.second}; // 这里r是正索引
        qry.pop_back();
      } else
        break;
    }

    now += S.size() - o; // 累计已处理的对数

    // 将当前l插入集合，为后续更小的l做准备
    S.insert({a[l], l});
  }

  FOR(i, 1, q) printf("%d %d\n", ans[i].fi, ans[i].se);
  return 0;
}